﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Threading;

namespace Kaixin.House.Ranch
{
    using Kaixin.Tools;

    public class Ranch
    {
        public enum ActionType
        {
            HarvestProduct = 0,
            HarvestAnimal,
            ProductAnimal,
            Water,
            Grass,
            Carrot,
        }

        private Network _network;
        private string _uid;           // your uid 
        private Friend _friend = null; // friend (owner) 
        private string _verify;        // verify code 

        public int Water = 0;
        public int Grass = 0;
        //public int Carrot = 0;

        public List<Product> Products = new List<Product>();
        public List<Animal> Animals = new List<Animal>();

        public Ranch(string uid, Friend friend, string verify,
            Network network)
        {
            _uid = uid;
            _friend = friend;
            _verify = verify;
            _network = network;
        }

        public void UpdateInfo()
        {
            try
            {
                string url = Consts.RootURL +  Consts.RanchConfUrl +
                    "?verify=" + _verify + "&fuid=" + _friend.Uid; 

                string RespXml = _network.CallUrl(url);
                XMLParser xmlParser = new XMLParser(RespXml);

                string tmp = xmlParser.GetNodeValue("/conf/water");
                Water = (tmp != null && !"".Equals(tmp)) ? Convert.ToInt32(tmp) : 0;
                tmp = xmlParser.GetNodeValue("/conf/grass");
                Grass = (tmp != null && !"".Equals(tmp)) ? Convert.ToInt32(tmp) : 0;

                Products.Clear();
                Animals.Clear();

                XmlNodeList nodelist = xmlParser.GetNodeList("/conf/product2");
                for (int i = 0; i < nodelist.Count; i++)
                {
                    if (nodelist.Item(i).NodeType == XmlNodeType.Text)
                        continue;
                    Products.Add(XmlNodeToProduct(nodelist.Item(i)));
                }

                nodelist = xmlParser.GetNodeList("/conf/animals");
                for (int i = 0; i < nodelist.Count; i++)
                {
                    if (nodelist.Item(i).NodeType == XmlNodeType.Text)
                        continue;
                    Animals.Add(XmlNodeToAnimal(nodelist.Item(i)));
                }
            }
            catch (Exception)
            { 
            }
        }

        private Product XmlNodeToProduct(XmlNode node)
        {
            Product product = new Product(_uid, _friend, _verify, _network);
            try
            {
                XmlElement element = (XmlElement)node;

                product.Name = element.GetElementsByTagName("pname").Item(0).InnerText;
                product.SKey = element.GetElementsByTagName("skey").Item(0).InnerText;
                product.Num = Convert.ToInt32(element.GetElementsByTagName("num").Item(0).InnerText);
                product.StealNum = Convert.ToInt32(element.GetElementsByTagName("stealnum").Item(0).InnerText);

                string tips = element.GetElementsByTagName("tips").Item(0).InnerText;
                if (!(tips.IndexOf("距下次可偷") < 0))
                    product.Theived = true;

                return product;
            }
            catch (Exception)
            {
                return product;
            }
        }

        private Animal XmlNodeToAnimal(XmlNode node)
        {
            Animal animal = new Animal(_uid, _friend, _verify, _network);
            try
            {
                XmlElement element = (XmlElement)node;

                animal.Name = element.GetElementsByTagName("aname").Item(0).InnerText;
                animal.AnimalSid = element.GetElementsByTagName("animalsid").Item(0).InnerText;

                string tmp = element.GetElementsByTagName("status").Item(0).InnerText;
                animal.Status = (tmp != null && !"".Equals(tmp)) ? Convert.ToInt32(tmp) : 0;

                tmp = element.GetElementsByTagName("fstatus").Item(0).InnerText;
                animal.FStatus = (tmp != null && !"".Equals(tmp)) ? Convert.ToInt32(tmp) : 0;

                tmp = element.GetElementsByTagName("bstat").Item(0).InnerText;
                animal.BStatus = (tmp != null && !"".Equals(tmp)) ? Convert.ToInt32(tmp) : -1;

                return animal;
            }
            catch (Exception)
            {
                return animal;
            }
        }

        public void DoWater()
        {
            if (Water < 50)
            {
                string url = Consts.RootURL + Consts.RanchWaterUrl;
                string data = "&verify=" + _verify + "&fuid=" + _friend.Uid;

                try
                {
                    string respXML = _network.PostData(url, Encoding.ASCII.GetBytes(data));
                    XMLParser parser = new XMLParser(respXML);
                    if ("succ".Equals(parser.GetNodeValue("/data/ret")))
                    {
                        TextOutput.PrintLine("Water: " + _friend.Name + " "
                            + "succ");
                    }
                    else
                    {
                        TextOutput.PrintLine("Water: " + _friend.Name + " "
                            + "Fail " + parser.GetNodeValue("/data/reason"));
                    }
                }
                catch (Exception)
                {
                }
            }
        }

        public void DoFood(Food.FoodType type, int num)
        {
            if (type == Food.FoodType.Grass && Grass > 150)
                return;

            string url = Consts.RootURL + Consts.RanchFoodUrl;
            string data = string.Format("verify={0}&fuid={1}&foodnum={2}&seedid={3}", 
                _verify, _friend.Uid, num, Food.GetSeedIdByType(type));

            try
            {
                string respXML = _network.PostData(url, Encoding.ASCII.GetBytes(data));
                XMLParser parser = new XMLParser(respXML);
                if ("succ".Equals(parser.GetNodeValue("/data/ret")))
                {
                    TextOutput.PrintLine("Food: " + _friend.Name + " " + type + " " + num
                        + " succ");
                }
                else
                {
                    TextOutput.PrintLine("Food: " + _friend.Name + " "
                        + "Fail " + parser.GetNodeValue("/data/reason"));
                }
            }
            catch (Exception)
            {
            }
        }

        private void DoGrassOne()
        {
            DoFood(Food.FoodType.Grass, 1);
        }

        public void DoGrass(int num)
        {
            DoFood(Food.FoodType.Grass, num);
        }

        private void DoCarrotOne()
        {
            DoFood(Food.FoodType.Carrot, 1);
        }

        public void DoCarrot(int num)
        {
            DoFood(Food.FoodType.Carrot, num);
        }

        public void HarvestProduct()
        {
            int count = 0;
            TextOutput.PrintLine("Harvest " + _friend.Name + "...");

            for (int i = 0; i < Products.Count; i++)
                if (Products[i].CanHarvest())
                {
                    int result = Products[i].Harvest();
                    if (result == 1)
                        count++;
                }
            TextOutput.PrintLine("End Harvest " + _friend.Name + ": Total " + count);
        }

        public void HarvestAnimal()
        {
            int count = 0;
            TextOutput.PrintLine("Harvest " + _friend.Name + "...");

            for (int i = 0; i < Animals.Count; i++)
                if (Animals[i].CanHarvest())
                {
                    if (Animals[i].Harvest())
                        count++;
                }
            TextOutput.PrintLine("End Harvest " + _friend.Name + ": Total " + count);
        }

        public void ProductAnimal()
        {
            int count = 0;
            TextOutput.PrintLine("Product " + _friend.Name + "...");

            for (int i = 0; i < Animals.Count; i++)
                if (Animals[i].CanProduct())
                {
                    if (Animals[i].Product())
                        count++;
                }
            TextOutput.PrintLine("End Product " + _friend.Name + ": Total " + count);
        }

        public void DoAction(ActionType type)
        {
            Thread ActionThread = null;
            switch (type)
            { 
                case ActionType.Water:
                    ActionThread = new Thread(new ThreadStart(DoWater));
                    break;
                case ActionType.Grass:
                    ActionThread = new Thread(new ThreadStart(DoGrassOne));
                    break;
                case ActionType.Carrot:
                    ActionThread = new Thread(new ThreadStart(DoCarrotOne));
                    break;
                case ActionType.HarvestAnimal:
                    ActionThread = new Thread(new ThreadStart(HarvestAnimal));
                    break;
                case ActionType.HarvestProduct:
                    ActionThread = new Thread(new ThreadStart(HarvestProduct));
                    break;
                case ActionType.ProductAnimal:
                    ActionThread = new Thread(new ThreadStart(ProductAnimal));
                    break;
            }

            if (ActionThread != null)
            {
                ActionThread.IsBackground = true;
                ActionThread.Start();
            }
        }

    }
}
